package com.apobates.forum.core.service;

import com.apobates.forum.core.ImageIOMeta;
import com.apobates.forum.core.entity.Posts;
import com.apobates.forum.core.entity.proxy.PostsReplica;
import com.apobates.forum.event.elderly.ActionEventCulpritor;
import com.apobates.forum.utils.lang.ReplicableException;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * 回复的业务接口
 *
 * @author xiaofanku
 * @since 20200510
 */
public interface PostsService {
    /**
     * 创建一条回复, 操作成功后会发送通知(PostsPublishEvent)
     *
     * @param boardGroupId 版块组(卷)ID
     * @param boardId 版块ID
     * @param topicId 话题ID
     * @param content 回复的内容
     * @param imageIO 图片存储信息
     * @param culpritor 操作的肇事信息
     * @return
     */
    long create(int boardGroupId, long boardId, long topicId, String content, ImageIOMeta imageIO, ActionEventCulpritor culpritor);
    
    /**
     * 编辑回复内容, 只能是回复(Posts.reply=true)的记录
     *
     * @param id 回复ID
     * @param content 更新的回复内容
     * @param imageIO 图片存储信息
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> edit(long id, String content, ImageIOMeta imageIO, ActionEventCulpritor culpritor);
    
    /**
     * 删除回复
     *
     * @param id 回复ID
     * @param culpritor 操作的肇事信息
     * @return
     */
    Optional<Boolean> remove(long id, ActionEventCulpritor culpritor);
    
    /**
     * 查看指定话题下的所有回复,包括楼主的话题内容,同时加载会员信息
     *
     * @param topicId 话题ID
     * @param pageable 分页请求参数
     * @return
     */
    Page<PostsReplica> getAll(long topicId, Pageable pageable);
    
    /**
     * 查看指定话题下的所有回复,不包括楼主的话题内容
     *
     * @param topicId 话题ID
     * @param pageable 分页请求参数
     * @return
     */
    Page<Posts> getAllReply(long topicId, Pageable pageable);
    
    /**
     * 查看指定话题下的所有回复,不包括楼主的话题内容.同时加载会员对象并对回复内容进行图片解码
     *
     * @param topicId 话题ID
     * @param pageable 分页请求参数
     * @param imageIO 图片存储信息
     * @param lazyLoad 是否懒加载回复内容中的图片; true懒加载,false不懒加载
     * @param imageScale 图片的尺寸,若为null表示自动
     * @return
     */
    Page<PostsReplica> getAllReply(long topicId, Pageable pageable, ImageIOMeta imageIO, boolean lazyLoad, String imageScale);
    
    /**
     * 查看话题中指定会员的所有回复,不包括楼主的话题内容.同时加载会员对象并对回复内容进行图片解码
     *
     * @param topicId 话题ID
     * @param filterMemeberId 回复者ID/过滤的会员ID
     * @param pageable 分页请求参数
     * @param imageIO 图片存储信息
     * @param lazyLoad 是否懒加载回复内容中的图片; true懒加载,false不懒加载
     * @param imageScale 图片的尺寸,若为null表示自动
     * @return
     */
    Page<PostsReplica> getAllReplyFilterAuthor(long topicId, long filterMemeberId, Pageable pageable, ImageIOMeta imageIO, boolean lazyLoad, String imageScale);
    
    /**
     *
     * @param topicIdList
     * @return
     */
    Stream<Posts> getTopicLordContent(List<Long> topicIdList);
    
    /**
     * 自参考日期以后版块最近的回复
     *
     * @param topicId 话题ID
     * @param prevUnixStamp 参考日期
     * @return
     */
    Stream<Posts> getRecentByUnixStamp(long topicId, int prevUnixStamp);
    
    /**
     * 查看指定话题最近的回复,忽略状态值;以entryDateTime倒序 服务于策略检查
     *
     * @param topicId 话题ID
     * @param size 显示的数量
     * @return
     */
    Stream<Posts> getRecentForTopicIgnoreStatus(long topicId, int size);
    
    /**
     * 查看话题最近的回复,不包括楼主的回复,并对回复内容进行解码(RSS)
     *
     * @param topicId 话题ID
     * @param size 显示的数量
     * @param imageIO 图片存储信息
     * @param lazyLoad 是否懒加载回复内容中的图片; true懒加载,false不懒加载
     * @return
     */
    Stream<Posts> getRecentForRSS(long topicId, int size, ImageIOMeta imageIO, boolean lazyLoad);
    
    /**
     * 查看指定的回复, 并对内容进行解码(编辑内容)
     *
     * @param id 回复ID
     * @param imageIO 图片存储信息
     * @param lazyLoad 是否懒加载回复内容中的图片; true懒加载,false不懒加载
     * @param imageScale 图片的尺寸,若为null表示自动
     * @return
     */
    Optional<Posts> getPostsContentForQuote(long id, ImageIOMeta imageIO, boolean lazyLoad, String imageScale)throws IllegalArgumentException;
    
    /**
     * 查看指定的回复, 并对内容进行解码(编辑内容)
     *
     * @param id 回复ID
     * @param imageIO 图片存储信息
     * @return
     */
    Optional<Posts> getPostsContentForEdit(long id, ImageIOMeta imageIO)throws IllegalArgumentException;
    
    /**
     * 查看指定的回复, 并对内容进行解码(编辑话题)
     *
     * @param topicId 话题ID
     * @param imageIO 图片存储信息
     * @return
     */
    Optional<PostsReplica> getPostsContentForEditByTopic(long topicId, ImageIOMeta imageIO)throws IllegalArgumentException,ReplicableException;
    
    /**
     * 查看指定的回复
     *
     * @param id 回复ID
     * @return
     */
    Optional<Posts> get(long id);
    
    /**
     * 查看话题的内容, 即1楼的内容. 级联加载话题
     * 
     * @param topicId 话题ID
     * @return
     */
    Optional<PostsReplica> getTopicContent(long topicId);
    
    /**
     * 查看指定回复, 级联加载话题
     * 
     * @param id 回复ID
     * @param topicId 话题ID
     * @return
     */
    Optional<PostsReplica> get(long id, long topicId);
    
    /**
     * 查看指定话题的回复最大楼层
     *
     * @param topicId 话题ID
     * @return
     */
    long maxFloor(long topicId);
    
    /**
     * 查看指定话题的回复当前多少页
     *
     * @param topicId 话题ID
     * @param pageSize 每页显示的回复数
     * @return
     */
    long getTopicPageSize(long topicId, int pageSize);
    
    /**
     * 统计指定回复者在话题中的回复次数, 1楼不在统计之列.忽略状态值
     *
     * @param topicId 话题ID
     * @param replyer 回复者/会员Id
     * @return
     */
    long countRepliesSize(long topicId, long replyer);
    
    /**
     * 统计指定话题的回复数, 1楼不在统计之列.忽略状态值
     *
     * @param topicId 话题ID
     * @return
     */
    long countRepliesSize(long topicId);
}